﻿/*
 * MemBuffer.cpp
 *
 *  Created on: 2014年6月7日
 *      Author: terry
 */

#include "MemBuffer.h"
#include <utility>

MemBuffer::MemBuffer():
	m_capacity(),
	m_length(),
	m_data()
{
}

MemBuffer::~MemBuffer()
{
	cleanup();
}

MemBuffer::MemBuffer(size_t capacity):
	m_capacity(),
	m_length(),
	m_data()
{
	ensure(capacity);
}

MemBuffer::MemBuffer(const MemBuffer& other):
	m_capacity(),
	m_length(),
	m_data()
{
	assign(other);
}

MemBuffer& MemBuffer::operator = (const MemBuffer& other)
{
	assign(other);
	return (*this);
}

void MemBuffer::assign(const MemBuffer& other)
{
	ensure(other.size());

	if (other.size() > 0)
	{
		memcpy(m_data, other.m_data, other.size());
	}

	m_length = other.size();
}

uint8_t* MemBuffer::data()
{
	return m_data;
}

size_t	MemBuffer::size() const
{
	return m_length;
}

size_t	MemBuffer::capacity() const
{
	return m_capacity;
}

bool MemBuffer::empty() const
{
	return (m_length == 0);
}

void MemBuffer::resize(size_t length)
{
	ensure(length);

	m_length = length;
}

bool MemBuffer::ensure(size_t capacity)
{
	if (capacity <= m_capacity)
	{
		return false;
	}

	size_t newCapacity = capacity;
	if (m_capacity != 0)
	{
		newCapacity = m_capacity;
		while (newCapacity < capacity)
		{
			newCapacity = newCapacity * 2;
		}
	}

	uint8_t* buffer = new uint8_t[newCapacity];

	if (m_length > 0)
	{
		memcpy(buffer, m_data, m_length);
	}

	std::swap(m_data, buffer);
	m_capacity = newCapacity;
	m_data[m_length] = '\0';

	delete[] buffer;

	return true;
}

void MemBuffer::clear()
{
	m_length = 0;
}

bool MemBuffer::write(const uint8_t* data, size_t length)
{
	ensure(m_length + length);
	memcpy(m_data + m_length, data, length);
	m_length += length;
	return true;
}

bool MemBuffer::write(const char* data, size_t length)
{
	return	write((const uint8_t*)data, length);
}

void MemBuffer::cleanup()
{
	if (!m_data)
	{
		return;
	}

	m_length = 0;
	m_capacity = 0;
	delete[] m_data;
	m_data = NULL;
}


